<?php
/**
 * 后台customers管理员模型
 * Author: lyun
 * Date: 2018/3/23
 * Created by Panxsoft.
 */


namespace App\Models\Admin;

use App\Exceptions\ApiErrCode;
use App\Exceptions\ApiException;
use App\Http\Middleware\CustomerAuth;
use App\Models\Concerns\DeSensitive;
use App\Models\Concerns\ScopeFilterable;
use App\Models\Customer\Customer;
use App\Services\Utils\Guard;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Traits\HasRoles;
use Tymon\JWTAuth\Contracts\JWTSubject as AuthenticatableUserContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

/**
 * Class CustomerAdmin
 *
 * @method static self role(array|string $roles)
 * @method static self filterIsSuperMan()
 * @property int $id
 * @property int is_deleted
 * @property int customer_id
 * @property Customer customer
 * @property string account
 * @property string name
 * @property string email
 * @property string language
 * @property Role[]|Collection roles
 *
 * @mixin Builder
 * @package App\Models\Admin
 */
class CustomerAdmin extends Authenticatable implements
    CanResetPasswordContract,
    AuthenticatableUserContract
{
    use HasRoles;
    use ScopeFilterable;
    use DeSensitive;

    const IS_NOT_DELETED = 0; // 后台管理员启用
    const IS_DELETED = 1;     // 后台管理员禁用
    const GUARD_NAME = 'agent';     // 后台guard

    const SUPER_MAN = '超管';  // 超管的角色名称，数据库中是中文
    const FINANCE = '财务';  // 财务的角色名称，数据库中是中文

    const SUPER_MAN_EN = 'SUPER_MAN';
    const FINANCE_EN = 'FINANCE';

    const ROLE_EN_TO_CN_MAP = [
        self::SUPER_MAN_EN => self::SUPER_MAN,
        self::FINANCE_EN   => self::FINANCE,
    ];

    protected $guard_name = Guard::ADMIN_CUSTOMER;

    protected $table = 'customer_admins';

    protected $guarded = [];

    protected $hidden = ['password', 'remember_token', 'reset_token'];

    protected $casts = [
        'id'          => 'int',
        'sex'         => 'int',
        'is_deleted'  => 'int',
        'customer_id' => 'int',
        'phone'       => 'string',
    ];

    /**
     * @return \Closure
     */
    public static function customerWithEnabledQuery(): \Closure
    {
        return function (HasMany $query) {
            $query->where('is_deleted', self::IS_NOT_DELETED);
        };
    }

    /**
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey(); // Eloquent model method
    }

    /**
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }

    public function customer()
    {
        return $this->belongsTo(Customer::class, 'customer_id', 'id');
    }

    /**
     * @param $value
     * @return mixed
     */
    public function setPasswordAttribute(?string $value): void
    {
        if ($value) {
            $this->attributes['password'] = Hash::make($value);
        }
    }

    /**
     * @param Builder $query
     * @return Builder
     */
    public function scopeFilterIsSuperMan(Builder $query)
    {
        return $query->where('id', '<>', Guard::customerAdmin()->id);
    }

    /**
     * @return bool
     */
    public static function isGuardSuperAdmin(): bool
    {
        return Guard::isCustomerSuperAdmin();
    }

    /**
     * @return bool
     */
    public function isSuperMan(): bool
    {
        return $this->hasRole(self::SUPER_MAN);
    }


    /**
     * @deprecated - 修改当前管理员职员权限 （没有找到使用）
     *
     * @param $role_name
     * @param CustomerAdmin $customer_admin
     * @return $this|bool
     * @throws \Throwable
     */
    public function updateRole($role_name, CustomerAdmin $customer_admin)
    {
        // 感觉当前登录的用户（超管）不应该显示在index方法中，至少保证系统中有一个超管的的角色，只有超管才有职员管理模块的操作权限。
        $role_ids = $customer_admin->roles->pluck('id')->all(); // 如果提交的是role_name ???

        $request_role_ids = [$role_name];

        if (!count(array_diff($role_ids, $request_role_ids))) return true; // 没有修改权限，直接通过

        throw_unless(
            $this->isSuperMan(),
            ApiException::class,
            ApiErrCode::NOT_CAN_UPDATE_ROLE,
            trans('admin.only_super_admin_edit_role'));

        throw_if(
            ($this->isSuperMan() && $customer_admin->id == $this->id),
            ApiException::class,
            ApiErrCode::NOT_CAN_UPDATE_ROLE,
            trans('admin.can_not_edit_self_role'));

        return $customer_admin->syncRoles($role_name);
    }
}
